#include<windows.h>
#include<d3d9.h>
#include<d3dx9.h> 

int int_AppRunning = 1;

LRESULT CALLBACK OurWindowProcedure(HWND han_Wind, UINT uint_Message, WPARAM parameter1, LPARAM parameter2)
{
	switch (uint_Message)
	{
	case WM_KEYDOWN:
		{
			int_AppRunning = 0;
			break;
		}
		break;
	}
	return DefWindowProc(han_Wind, uint_Message, parameter1, parameter2);
}

HWND NewWindow(LPCTSTR str_Title, int int_XPos, int int_YPos, int int_Width, int int_Height)
{
	WNDCLASSEX wnd_Structure;
	wnd_Structure.cbSize = sizeof(WNDCLASSEX);
	wnd_Structure.style = CS_HREDRAW | CS_VREDRAW;

	wnd_Structure.lpfnWndProc = OurWindowProcedure;
	wnd_Structure.cbClsExtra = 0;
	wnd_Structure.cbWndExtra = 0;
	wnd_Structure.hInstance = GetModuleHandle(NULL);
	wnd_Structure.hIcon = NULL;
	wnd_Structure.hCursor = NULL;
	wnd_Structure.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
	wnd_Structure.lpszMenuName = NULL;
	wnd_Structure.lpszClassName = L"WindowClassName";
	wnd_Structure.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	RegisterClassEx(&wnd_Structure);
	return CreateWindowEx(WS_EX_CONTROLPARENT, L"WindowClassName", str_Title, WS_OVERLAPPED |
		WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, int_XPos, int_YPos, int_Width,
		int_Height, NULL, NULL, GetModuleHandle(NULL), NULL);
}

LPDIRECT3DDEVICE9 InitializeDevice(HWND han_WindowToBindTo)
{
	LPDIRECT3D9 p_dx_Object;

	p_dx_Object = Direct3DCreate9(D3D_SDK_VERSION);
	if (p_dx_Object == NULL)
	{
		MessageBox(han_WindowToBindTo, L"DirectX Runtime library not installed!", L"InitializeDevice()", MB_OK);
	}

	D3DPRESENT_PARAMETERS dx_PresParams;

	ZeroMemory( &dx_PresParams, sizeof(dx_PresParams) );
	dx_PresParams.Windowed = TRUE;
	dx_PresParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
	dx_PresParams.BackBufferFormat = D3DFMT_UNKNOWN;

	LPDIRECT3DDEVICE9 p_dx_Device;

	if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, han_WindowToBindTo, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device)))
	{
		if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, han_WindowToBindTo, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device)))
		{
			MessageBox(han_WindowToBindTo, L"Failed to create even the reference device!", L"InitializeDevice()",MB_OK);
		}
	}

	return p_dx_Device;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, LPSTR lpcmdline, int nCmdShow)
{
	HWND han_Window = NewWindow(L"DirectX C++ Tutorial", 100, 100, 500, 500);
	MSG msg_Message;

	LPDIRECT3DDEVICE9 p_Device = InitializeDevice(han_Window);

	while(int_AppRunning)
	{
		if(PeekMessage(&msg_Message,han_Window,0,0,PM_REMOVE))
		{
			DispatchMessage(&msg_Message);
		}
	}

	p_Device->Release();
	DestroyWindow(han_Window);

	return 0;
}